package us.mooresr.geartrack.client.core.presenter;

import java.util.List;

import com.gwtplatform.dispatch.shared.DispatchAsync;
import com.gwtplatform.mvp.client.HasUiHandlers;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.ProxyCodeSplit;
import com.gwtplatform.mvp.client.annotations.NameToken;
import us.mooresr.geartrack.client.place.NameTokens;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.google.inject.Inject;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtplatform.mvp.client.proxy.RevealContentEvent;
import us.mooresr.geartrack.client.core.presenter.MainPresenter;
import us.mooresr.geartrack.client.events.PersonChangedEvent;
import us.mooresr.geartrack.client.events.PersonCreatedEvent;
import us.mooresr.geartrack.client.events.ItemCreatedEvent;
import us.mooresr.geartrack.client.events.PersonDeletedEvent;
import us.mooresr.geartrack.shared.action.PutItemAction;
import us.mooresr.geartrack.shared.action.PutItemResult;
import us.mooresr.geartrack.shared.action.PutPersonAction;
import us.mooresr.geartrack.shared.action.PutPersonResult;
import us.mooresr.geartrack.shared.action.DeletePersonAction;
import us.mooresr.geartrack.shared.action.DeletePersonResult;
import us.mooresr.geartrack.shared.action.GetAllItemsAction;
import us.mooresr.geartrack.shared.action.GetAllItemsResult;
import us.mooresr.geartrack.shared.action.GetAllPeopleAction;
import us.mooresr.geartrack.shared.action.GetAllPeopleResult;
import us.mooresr.geartrack.shared.model.Person;

public class PeoplePresenter extends
		Presenter<PeoplePresenter.MyView, PeoplePresenter.MyProxy> 
		implements PeopleUiHandlers {
	
	private final DispatchAsync dispatcher;

	public interface MyView extends View, HasUiHandlers<PeopleUiHandlers> {
		public void setPersonList(List<Person> person);
		public void addPersonToList(Person person);
		public void removePersonFromList(Person person);
		public void updateListEntry(Person person);
	}

	@ProxyCodeSplit
	@NameToken(NameTokens.people)
	public interface MyProxy extends ProxyPlace<PeoplePresenter> {
	}

	@Inject
	public PeoplePresenter(final EventBus eventBus, final MyView view,
			final MyProxy proxy, DispatchAsync dispatcher) {
		super(eventBus, view, proxy);
		getView().setUiHandlers(this);
		
		this.dispatcher = dispatcher;
	}

	@Override
	protected void revealInParent() {
		RevealContentEvent.fire(this, MainPresenter.TYPE_SetMainContent, this);
	}

	@Override
	protected void onBind() {
		super.onBind();
		
		addRegisteredHandler(PersonCreatedEvent.getType(), new PersonCreatedEvent.PersonCreatedHandler() {
			
			@Override
			public void onBorrowerCreated(PersonCreatedEvent event) {
				getView().addPersonToList(event.getBorrower());
				
			}
			
		});
		
		addRegisteredHandler(PersonDeletedEvent.getType(), new PersonDeletedEvent.PersonDeletedHandler() {

			@Override
			public void onPersonDeleted(PersonDeletedEvent event) {
				getView().removePersonFromList(event.getPerson());
				
			}
			
		});
		
		addRegisteredHandler(PersonChangedEvent.getType(), new PersonChangedEvent.PersonChangedHandler() {
			
			@Override
			public void onPersonChanged(PersonChangedEvent event) {
				getView().updateListEntry(event.getPerson());
				
			}
		});
		

	}
	
	@Override
	public void onReveal() {
		super.onReveal();
		
		// Launch a request to get the borrower list data
		GetAllPeopleAction action = new GetAllPeopleAction();
		
		dispatcher.execute(action,  new AsyncCallback<GetAllPeopleResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(GetAllPeopleResult result) {
				getView().setPersonList(result.getPeople());
				
			}
			
		});	
	}

	@Override
	public void deletePerson(Person person) {
		DeletePersonAction action = new DeletePersonAction(person);
		
		dispatcher.execute(action, new AsyncCallback<DeletePersonResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(DeletePersonResult result) {
				PersonDeletedEvent.fire(getEventBus(), result.getPersonOut());
			}
			
		});
		
	}

	@Override
	public void addPerson(Person person) {
		PutPersonAction action = new PutPersonAction(person);
		
		dispatcher.execute(action, new AsyncCallback<PutPersonResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(PutPersonResult result) {
				// The update was successful.  Fire an event to tell everyone about it.
				PersonCreatedEvent.fire(getEventBus(), result.getPersonOut());
			}
			
		});
		
	}

	@Override
	public void updatePerson(Person person) {
		PutPersonAction action = new PutPersonAction(person);
		
		dispatcher.execute(action, new AsyncCallback<PutPersonResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(PutPersonResult result) {
				// The update was successful.  Fire an event to tell everyone about it.
				PersonChangedEvent.fire(getEventBus(), result.getPersonOut());
			}
			
		});
		
	}
}
